﻿/*
 * Created by SharpDevelop.
 * User: Intel
 * Date: 03.02.2014
 * Time: 11:03
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.IO;
namespace Region
{
  /// <summary>
  /// Description of File.
  /// </summary>
  public class RegionFile
  {
    const Int32 SizeBlock = 256*1024; 
    /*public class FileStream: Stream
    {
      public override void Write(byte[] buffer, int offset, int count)
			{
			}
      public override int Read(byte[] bytes, int offset, int count)
      {
        return 0;
      }
      public override void SetLength(long length)
      {
        
      }
      public override void Flush()
      {
      }
      public override long Seek(long offset, SeekOrigin origin)
      {
        return 0;
      }
      public override long Position
		  {
        get{return 0;}
        set{}
		  }
      public override long Length
		  {
			 get{return 0;}
		  }
      public override bool CanRead
  		{
        get{return false;}
  		}
  		public override bool CanSeek
  		{
  			get{return false;}
  		}
  		public override bool CanWrite
		  {
  		  get{return false;}
		  }
    }*/
    Engine m_engine;
    Int64 m_Size;
    String m_FileUID;
    public Int64 Size{get{return m_Size;}}
    public RegionFile(Engine engine,String FileUID)
    {
      m_FileUID = FileUID;
      m_engine = engine;
    }
    byte[] readBlock(Int64 Offset)
    {
      if (Offset%SizeBlock!=0) return null;
      SQLResult r = m_engine.SQLSelect("SELECT * FROM fileschain WHERE FileUID=@FileUID AND Offset=@Offset", new SQLParam(){{"@FileUID",m_FileUID},{"@Offset",Offset}});
      if (r.Count==1)
        return (byte[])r[0]["Data"];
      else
        return null;
    }
    bool writeBlock(Int64 Offset,Byte[] Buff,Int32 BuffOffset,Int32 BuffSize)
    {
      if (Offset%SizeBlock!=0) return false;
      if (BuffSize>SizeBlock) return false;
      if (BuffSize<0) return false;
      Byte[] B = new Byte[BuffSize];
      Array.Copy(Buff,BuffOffset,B,0,BuffSize);
      m_engine.SQLEdit("REPLACE INTO fileschain SET FileUID=@FileUID, Offset=@Offset, Size=@Size, Data=@Data", new SQLParam(){{"@FileUID",m_FileUID},{"@Offset",Offset},{"@Size",B.Length},{"@Data",B}});
      return true;
    }
    bool clear()
    {
      m_engine.SQLEdit("DELETE FROM fileschain WHERE FileUID=@FileUID", new SQLParam(){{"@FileUID",m_FileUID}});
      return true;
    }
    public bool write(Stream stream)
    {
      Byte[] Buff = new Byte[SizeBlock];
      clear();
      Int32 rs = 0;
      Int64 Offset = 0;
      stream.Seek(0, SeekOrigin.Begin);
      do
      {
        rs = stream.Read(Buff,0,SizeBlock);
        writeBlock(Offset,Buff,0,rs);
        Offset += rs;
      } while(rs==SizeBlock);
      return true;
    }
    public bool read(Stream stream)
    {
      Byte[] Buff = null;
      Int64 Offset = 0;
      stream.Seek(0, SeekOrigin.Begin);
      do
      {
        Buff =  readBlock(Offset);
        stream.Write(Buff,0,Buff.Length);
        Offset += Buff.Length;
        if (Buff.Length!=SizeBlock) break;
      } while(true);
      return true;
    }
  }
}
